package com.sjzd.weixin.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sjzd.meeting.pojo.WxUser;
import com.sjzd.weixin.bean.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 *  微信工具类
 */
public class WxUtils {
    private static final Logger log = LoggerFactory.getLogger(WxUtils.class);

    // 获取普通access_token的url模板
    private static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";

    // 创建菜单接口的url模板
    private static String menu_url = " https://api.weixin.qq.com/cgi-bin/menu/create?access_token=%s";

    // 获取用户基本信息的url模板
    private static String user_info_url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid=%s&lang=zh_CN";

    // 封装access_token的实例
    private static AccessToken accessToken = AccessToken.getInstance();

    /**
     *  刷新接口令牌
     * @param appID
     * @param secret
     * @return
     */
    public static void refreshAccessToken(String appID, String secret) {
        String url = String.format(access_token_url, appID, secret);
        String jsonStr = httpRequest(url, "GET", null);
        JSONObject jsonObject = JSONObject.parseObject(jsonStr);
        try {
            accessToken.setAccess_token(jsonObject.getString("access_token"));
            accessToken.setExpires_in(jsonObject.getInteger("expires_in"));
        } catch (Exception e) {
            log.error("刷新access_token失败，errcode : {}, errmsg : {}", jsonObject.getInteger("errcode"),
                    jsonObject.getString("errmsg"));
        }
    }

    /**
     *  从微信服务器获取接口令牌json格式字符串信息
     */
    public static String httpRequest(String url, String requestMethod, String postStr) {
        String jsonStr = null;
        try {
            URL u = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) u.openConnection();
            conn.setRequestMethod(requestMethod);
            if (requestMethod.equalsIgnoreCase("POST")) {
                conn.setDoOutput(true);
            }
            // 确保建立连接
            conn.connect();

            OutputStream out = null;
            if (null != postStr && !("").equals(postStr)) {
                out = conn.getOutputStream();
                // 防止乱码
                out.write(postStr.getBytes("UTF-8"));
                // 释放资源
                out.close();
            }
            InputStream in = conn.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(in, "utf-8"));
            StringBuilder sb = new StringBuilder();
            String temp = null;
            while ((temp = br.readLine()) != null){
                sb.append(temp);
            }
            jsonStr = sb.toString();

            // 释放资源
            in.close();
            conn.disconnect();
        } catch (Exception e) {
           log.error("与微信服务器连接失败！error{}", e.getCause());
        }
        return jsonStr;
    }

    /**
     * 创建页面菜单
     */
    public static void refreshMenu(Menu menu) {
        String url = String.format(menu_url, accessToken.getAccess_token());
        String postStr = JSON.toJSON(menu).toString();
        String result = httpRequest(url, "POST", postStr);
        JSONObject jsonObject = JSONObject.parseObject(result);
        if (0 != jsonObject.getInteger("errcode")) {
            log.error("创建菜单失败！errcode : {}, errmsg : {}", jsonObject.getInteger("errcode"),
                    jsonObject.getString("errmsg"));
        }
    }



    /**
     *  获取access_token
     */
    public static String getAccessToken() {
        return accessToken.getAccess_token();
    }

    /**
     *  获取用户的基本信息
     * @param openId
     * @return
     */
    public static WxUser extractUserInfoJsonToWxUser(String openId) {
        String url = String.format(user_info_url, accessToken.getAccess_token(), openId);
        String json = httpRequest(url, "GET", null);
        return convertJsonToObject(json, WxUser.class);
    }

    /**
     *  将json字符串转换为相应class对象
     */
    private static <T> T convertJsonToObject(String json, Class<T> clazz) {
        try {
            T t =  JSON.parseObject(json, clazz);
            return t;
        } catch (Exception e) {
            JSONObject jsonObject = JSON.parseObject(json);
            log.error("json字符串在转换为" + clazz + "对象时失败，errcode:{} errmsg:{}", jsonObject.getInteger("errcode"), jsonObject.getString("errmsg"));
        }
        return null;
    }
}
